package ga;

import ga.ObjTipo.TipoDeObjTipo;

//TODO quitar el Undef una vez debuggueado
abstract public class Instruccion {
	public enum ICOD {SUM,RESTA,MUL,DIV,AND,OR,EQ,NEQ,GT,GE,LT,LE,IR_F,IR_A,IR_IND,APILA,DESAPILA_DIR,APILA_DIR,
		APILA_TRUE,APILA_FALSE, NOT, MENOS,APILA_IND,DESAPILA,DESAPILA_IND,COPIA,LEER,ESCRIBIR,
		LIBERA,RESERVA, UNDEF, MUEVE};
	
    abstract public ICOD ci();
    
    public int arg1()  
    {
    	throw new UnsupportedOperationException("arg1");   
    } 
    public TipoDeObjTipo arg2()  
    {
    	throw new UnsupportedOperationException("arg2");   
    } 
    public static class ISuma 			extends Instruccion {
       ISuma() {} 
       public ICOD ci () {return ICOD.SUM;}
       public String toString() {return "SUMA";}
    }
    public static class IResta 			extends Instruccion {
        IResta() {} 
        public ICOD ci () {return ICOD.RESTA;}
        public String toString() {return "RESTA";}
     }
    public static class IMul 			extends Instruccion{
       IMul() {} 
       public ICOD ci () {return ICOD.MUL;}
       public String toString() {return "MUL";}
    }
    public static class IDiv 			extends Instruccion {
        IDiv() {} 
        public ICOD ci () {return ICOD.DIV;}
        public String toString() {return "DIV";}
     }
    public static class IOr 			extends Instruccion {
        IOr() {} 
        public ICOD ci () {return ICOD.OR;}
        public String toString() {return "OR";}
     }
    public static class IAnd 			extends Instruccion {
        IAnd() {} 
        public ICOD ci () {return ICOD.AND;}
        public String toString() {return "AND";}
     }
    public static class IEq 			extends Instruccion {
        IEq() {} 
        public ICOD ci () {return ICOD.EQ;}
        public String toString() {return "EQ";}
     }
    public static class INeq 			extends Instruccion {
        INeq() {} 
        public ICOD ci () {return ICOD.NEQ;}
        public String toString() {return "NEQ";}
     }
    public static class IGt 			extends Instruccion {
        IGt() {} 
        public ICOD ci () {return ICOD.GT;}
        public String toString() {return "GT";}
     }
    public static class IGe 			extends Instruccion {
        IGe() {} 
        public ICOD ci () {return ICOD.GE;}
        public String toString() {return "GE";}
     }
    public static class ILt 			extends Instruccion {
        ILt() {} 
        public ICOD ci () {return ICOD.LT;}
        public String toString() {return "LT";}
     }
    public static class ILe 			extends Instruccion {
        ILe() {} 
        public ICOD ci () {return ICOD.LE;}
        public String toString() {return "LE";}
     }
    public static class Ir_f 			extends Instruccion {
        Ir_f(Integer val) {
              this.val = val;    
         }   
        Ir_f(int val) {
            this.val = val;    
       }
         public ICOD ci () {return ICOD.IR_F;}
         public int arg1() {return val;}
         public String toString() {return "IR_F("+val+")";}
         private Integer val;
        
     }
    public static class Ir_a 			extends Instruccion {
        Ir_a(Integer val) {
        	this.val = val;  
         } 
        Ir_a(int val) {
              this.val = val;    
         }
         public ICOD ci () {return ICOD.IR_A;}
         public int arg1() {return val;}
         public String toString() {return "IR_A("+val+")";}
         private Integer val;
        
     }
    public static class Ir_Ind 			extends Instruccion {
    	Ir_Ind() {
         } 
         public ICOD ci () {return ICOD.IR_IND;}
         public String toString() {return "IR_IND";}        
     }
    public static class IApila 			extends Instruccion {
       IApila(String val) {
          try {
            this.val = Integer.valueOf(val).intValue();    
          }
          catch(NumberFormatException e) {
            this.val = 0;   
          }
       }   
       public ICOD ci () {return ICOD.APILA;}
       public int arg1() {return val;}
       public String toString() {return "APILA("+val+")";}
       private int val;
     }
    public static class IDesapila_dir 	extends Instruccion {
    	IDesapila_dir(String val) {
           try {
             this.val = Integer.valueOf(val).intValue();    
           }
           catch(NumberFormatException e) {
             this.val = 0;   
           }
        }   
        public ICOD ci () {return ICOD.DESAPILA_DIR;}
        public int arg1() {return val;}
        public TipoDeObjTipo arg2() {return arg2;}
        public String toString() {return "DESAPILA_DIR("+val+")";}
        private int val;
        private TipoDeObjTipo arg2;
      }
    public static class IApila_dir 		extends Instruccion {
        IApila_dir(String val) {
           try {
             this.val = Integer.valueOf(val).intValue();    
           }
           catch(NumberFormatException e) {
             this.val = 0;   
           }
        }   
        public ICOD ci () {return ICOD.APILA_DIR;}
        public int arg1() {return val;}
        public String toString() {return "APILA_DIR("+val+")";}
        private int val;
      }
    public static class IApila_true 	extends Instruccion {
        IApila_true() {}   
        public ICOD ci () {return ICOD.APILA_TRUE;}
        public String toString() {return "APILA_TRUE";}
      }
    public static class IApila_false 	extends Instruccion {
        IApila_false() {}   
        public ICOD ci () {return ICOD.APILA_FALSE;}
        public String toString() {return "APILA_FALSE";}
      }
    public static class INot 			extends Instruccion {
    	INot() {} 
        public ICOD ci () {return ICOD.NOT;}
        public String toString() {return "NOT";}
     }
    public static class IMenos 			extends Instruccion {
    	IMenos() {} 
        public ICOD ci () {return ICOD.MENOS;}
        public String toString() {return "MENOS";}
     }
    public static class ICopia 			extends Instruccion {
    	ICopia() {} 
        public ICOD ci () {return ICOD.COPIA;}
        public String toString() {return "COPIA";}
     }
    public static class IApilaInd 		extends Instruccion {
    	IApilaInd() {} 
        public ICOD ci () {return ICOD.APILA_IND;}
        public String toString() {return "APILA_IND";}
     }
    public static class IDesapilaInd 	extends Instruccion {
    	IDesapilaInd() {} 
        public ICOD ci () {return ICOD.DESAPILA_IND;}
        public String toString() {return "DESAPILA_IND";}
     }
    public static class IDesapila 		extends Instruccion {
    	IDesapila() {} 
        public ICOD ci () {return ICOD.DESAPILA;}
        public String toString() {return "DESAPILA";}
     }
    public static class ILeer 			extends Instruccion {
    	ILeer(TipoDeObjTipo t) {
    		this.val = t;
    	} 
        public ICOD ci () {return ICOD.LEER;}
        public String toString() {return "LEER("+val+")";}
        private TipoDeObjTipo val;
        public TipoDeObjTipo arg2() {return val;}
    }
    public static class IEscribir 		extends Instruccion {
    	 IEscribir(TipoDeObjTipo t) {
    		 this.val = t;
    	 } 
         public ICOD ci () {return ICOD.ESCRIBIR;}
         public String toString() {return "ESCRIBIR("+val+")";}
         private TipoDeObjTipo val;
         public TipoDeObjTipo arg2() {return val;}
    }
    public static class IReserva 		extends Instruccion {
    	IReserva (Integer val) {
    		this.val = val;
           }  
        public ICOD ci () {return ICOD.RESERVA;}
        public int arg1() {return val;}
        public String toString() {return "RESERVA("+val+")";}
        private int val;
   }
    public static class ILibera 		extends Instruccion {
    	ILibera(Integer val) {
            this.val = val;
           }  
        public ICOD ci () {return ICOD.LIBERA;}
        public int arg1() {return val;}
        public String toString() {return "LIBERA("+val+")";}
        private int val;
    }
    public static class IMueve 			extends Instruccion {
    	IMueve(Integer val) {
            this.val = val;
           }  
        public ICOD ci () {return ICOD.MUEVE;}
        public int arg1() {return val;}
        public String toString() {return "MUEVE("+val+")";}
        private int val;
     }
    public static class IUndef 			extends Instruccion {
    	String eti;
        IUndef(String et) {eti = et;} 
        public ICOD ci () {return ICOD.UNDEF;}
        public String toString() {return "UNDEF("+eti+")";}
     }


     public static Instruccion nuevaISuma() {
        if (isuma==null) {
           isuma = new ISuma(); 
        } 
        return isuma;
     }
     public static Instruccion nuevaIResta() {
         if (iresta==null) {
            iresta = new IResta(); 
         } 
         return iresta;
      }
     public static Instruccion nuevaIMul() {
        if (imul==null) {
           imul = new IMul(); 
        } 
        return imul;
     }
     public static Instruccion nuevaIDiv() {
         if (idiv==null) {
            idiv = new IDiv(); 
         } 
         return idiv;
      }
     public static Instruccion nuevaIAnd() {
         if (iand==null) {
            iand = new IAnd(); 
         } 
         return iand;
      }
     public static Instruccion nuevaIOr() {
         if (ior==null) {
            ior = new IOr(); 
         } 
         return ior;
      }
     public static Instruccion nuevaIEq() {
         if (ieq==null) {
            ieq = new IEq(); 
         } 
         return ieq;
      }
     public static Instruccion nuevaINeq() {
         if (ineq==null) {
            ineq = new INeq(); 
         } 
         return ineq;
      }
     public static Instruccion nuevaIGt() {
         if (igt==null) {
            igt = new IGt(); 
         } 
         return igt;
      }
     public static Instruccion nuevaIGe() {
         if (ige==null) {
            ige = new IGe(); 
         } 
         return ige;
      }
     public static Instruccion nuevaILt() {
         if (ilt==null) {
            ilt = new ILt(); 
         } 
         return ilt;
      }
     public static Instruccion nuevaILe() {
         if (ile==null) {
            ile = new ILe(); 
         } 
         return ile;
      }
     public static Instruccion nuevaIr_f(Integer val) {
         return new Ir_f(val); 
      }
     public static Instruccion nuevaIr_a(Integer val) {
         return new Ir_a(val); 
      } 
     public static Instruccion nuevaIr_Ind() {
    	 if (iirind==null) {
    		 iirind = new Ir_Ind(); 
          } 
          return iirind;
      } 
     public static Instruccion nuevaIApila(String val) {
        return new IApila(val); 
     }
     public static Instruccion nuevaIDesapila_dir(String val) {
         return new IDesapila_dir(val); 
      }
     public static Instruccion nuevaIApila_true() {
         if (ipatrue==null) {
        	 ipatrue = new IApila_true(); 
         } 
         return ipatrue;
      }
     public static Instruccion nuevaIApila_false() {
         if (ipafalse==null) {
        	 ipafalse = new IApila_false(); 
         } 
         return ipafalse;
      }
     public static Instruccion nuevaINot() {
         if (inot==null) {
         	inot = new INot(); 
         } 
         return inot;
      }    
     public static Instruccion nuevaIMenos() {
         if (imenos==null) {
            imenos = new IMenos(); 
         } 
         return imenos;
      }
     public static Instruccion nuevaIApila_dir(String val){
    	 return new IApila_dir(val); 
     }
 	 public static Instruccion nuevaIDesapila() {
		if (idesapila==null) {
 			idesapila = new IDesapila(); 
         } 
         return idesapila;
	 }
	 public static Instruccion nuevaICopia() {
		if (icopia==null) {
 			icopia = new ICopia(); 
         } 
         return icopia;
	 }
	 public static Instruccion nuevaIApilaInd() {
		if (iapilaind==null) {
 			iapilaind = new IApilaInd(); 
         } 
         return iapilaind;
	 }
	 public static Instruccion nuevaIDesapilaInd() {
		if (idesapilaind==null) {
 			idesapilaind = new IDesapilaInd(); 
         } 
         return idesapilaind;
	 }   
	 public static Instruccion nuevaILeer(TipoDeObjTipo t) {
			if (ileer==null) {
				ileer = new ILeer(t); 
	         } 
	         return ileer;
		 }    
	 public static Instruccion nuevaIEscribir(TipoDeObjTipo t) {
			if (iescribir==null) {
				iescribir = new IEscribir(t); 
	         } 
	         return iescribir;
		 }    
	 public static Instruccion nuevaIReserva(Integer val){
    	 return new IReserva(val); 
     }
	 public static Instruccion nuevaILibera(Integer val){
    	 return new ILibera(val); 
     }
	 public static Instruccion nuevaIMueve(Integer val){
    	 return new IMueve(val); 
     }
	 public static Instruccion nuevaUndef(String et) {
          return new IUndef(et); 
      } 
	 
     private static ISuma isuma					= null;
     private static IResta iresta				= null;
     private static IMul imul					= null;
     private static IDiv idiv					= null;
     private static IAnd iand					= null;
     private static IOr ior						= null;
     private static IEq ieq						= null;
     private static INeq ineq					= null;
     private static IGt igt						= null;
     private static IGe ige						= null;
     private static ILt ilt						= null;
     private static ILe ile						= null;
     private static IApila_true ipatrue 		= null;
     private static IApila_false ipafalse		= null;
     private static IMenos imenos 				= null;
     private static INot inot 					= null;
     private static IDesapila idesapila 		= null;
     private static ICopia icopia 				= null;
     private static IApilaInd iapilaind 		= null;
     private static IDesapilaInd idesapilaind 	= null;
     private static ILeer ileer 				= null;
     private static IEscribir iescribir 		= null;
     private static Ir_Ind iirind		 		= null;
     
}
